package com.jiubanqingchen.wish.org.appAction;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import com.jfinal.aop.Aop;
import com.jfinal.kit.Kv;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Record;
import com.jiubanqingchen.wish.framework.annotation.SqlKey;
import com.jiubanqingchen.wish.framework.base.service.ModelService;
import com.jiubanqingchen.wish.framework.base.user.IUser;
import com.jiubanqingchen.wish.framework.exception.WishException;
import com.jiubanqingchen.wish.framework.exception.WishExceptionKey;
import com.jiubanqingchen.wish.framework.security.AuthService;
import com.jiubanqingchen.wish.kit.BlankKit;
import com.jiubanqingchen.wish.model.models.AppAction;
import com.jiubanqingchen.wish.org.resourceAuthority.ResourceAuthorityService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author light_dust
 * @since 2021/4/25 17:51
 */
@SqlKey("org_appAction.list")
public class AppActionService extends ModelService<AppAction> {

    private static final Logger logger = LoggerFactory.getLogger(AppActionService.class);
    /**
     * 类
     */
    private final String actionTypeC = "Controller";
    /**
     * 方法
     */
    private final String actionTypeF = "Function";

    @Override
    public void preInsert(AppAction appAction, Record record, IUser _usr) {
        //如果接口默认没有配置父亲id 默认设置0
        if (StrKit.isBlank(appAction.getParentId())) {
            appAction.setParentId("0");
        }
        judgeAuthorityIsRepeat(appAction);
        //判断是存在相同的权限key如果存在则抛出异常
        super.preInsert(appAction, record, _usr);
    }

    @Override
    public void afterDelete(AppAction appAction, Record record, IUser _usr) throws WishException {
        ResourceAuthorityService resourceAuthorityService = Aop.get(ResourceAuthorityService.class);
        AuthService authService = Aop.get(AuthService.class);
        //如果接口类型为类 删除他的子接口
        String actionId = appAction.getActionId();
        String actionType = appAction.getActionType();
        List<String> roleIds = new ArrayList<>();
        if (actionTypeC.equals(actionType)) {
            List<AppAction> appActionList = where("parentId=?", actionId);
            if (BlankKit.notBlankList(appActionList)) {
                //获取接口关联的角色信息 需要先查询不然数据会被删除掉
                roleIds.addAll(resourceAuthorityService.findRoleIdByResourceIds(appActionList.stream().map(AppAction::getActionId).collect(Collectors.toList())));
                //由于只有两级接口所以可以直接删除
                deleteWhere("parentId=?", actionId);
                logger.info("正在删除接口类 [{}] {} 的子接口信息", appAction.getActionName(), actionId);
            }
        }
        //查找接口关联的角色信息 需要先查询不然数据会被删除掉
        roleIds.addAll(resourceAuthorityService.findRoleIdByResourceId(actionId));
        //删除资源权限信息
        resourceAuthorityService.deleteWhere("resourceId=?", actionId);
        logger.info("正在删除接口类 [{}] {} 的子接口信息", appAction.getActionName(), actionId);

        //查询接口关联的角色 清理掉这些角色的缓存信息
        roleIds.stream().distinct().collect(Collectors.toList()).forEach(authService::deleteRoleInterfaceAuthorityCache);

        super.afterDelete(appAction, record, _usr);
    }

    /**
     * 判断是否存在同样的actionKey
     *
     * @param appAction 接口对象
     */
    private void judgeAuthorityIsRepeat(AppAction appAction) throws WishException {
        String authorityKey = appAction.getAuthorityKey();
        Kv kv = new Kv().set("authorityKey", authorityKey);
        List<AppAction> appActionList = findList(kv);
        if (BlankKit.notBlankList(appActionList)) {
            throw new WishException(WishExceptionKey.AUTHORITY_IS_RE);
        }
    }

    /**
     * 初始化model controller 的基本接口
     *
     * @param actionId 接口id
     */
    public void initModelControllerAction(String actionId, IUser _usr) {
        AppAction appAction = AppAction.dao.findById(actionId);
        String[] keyArr = new String[]{"view", "add", "edit", "delete", "download", "upload"};
        String[] nameArr = new String[]{"查看", "新增", "编辑", "删除", "下载", "上传"};
        //获取父数据
        String authorityKey = appAction.getAuthorityKey();
        String actionName = appAction.getActionName();
        int sortNo = appAction.getSortNo();

        //处理待插入数据
        List<AppAction> appActionList = new ArrayList<>();
        for (int i = 0; i < keyArr.length; i++) {
            AppAction childAppAction = new AppAction();
            //设置父id 接口名称 接口key
            childAppAction.setParentId(actionId);
            childAppAction.setActionName(actionName + nameArr[i]);
            childAppAction.setAuthorityKey(authorityKey + ":" + keyArr[i]);
            childAppAction.setSortNo(Integer.parseInt(sortNo + "0" + (i + 1)));
            childAppAction.setActionType(actionTypeF);
            appActionList.add(childAppAction);
        }
        //批量插入数据
        insertBatch(appActionList, null, _usr);
    }

    /**
     * 获取接口树
     *
     * @param kv 参数
     */
    public List<Tree<String>> tree(Kv kv) {
        List<AppAction> appActionList = findList(kv);
        if (BlankKit.isBlankList(appActionList)) return null;
        //配置字段属性
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
        treeNodeConfig.setIdKey("actionId");
        treeNodeConfig.setNameKey("actionName");
        //添加插槽供前端使用
        Map<String, String> slotsMap = new HashMap<>();
        slotsMap.put("title", "custom");
        //自定义字段
        return TreeUtil.build(appActionList, "0", treeNodeConfig, (treeNode, tree) -> {
            tree.setId(treeNode.getActionId());
            tree.setParentId(treeNode.getParentId());
            tree.setName(treeNode.getActionName());
            tree.putExtra("authorityKey", treeNode.getAuthorityKey());
            tree.putExtra("slots", slotsMap);
        });
    }
}
